﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Model;
using BLL;
using Common;
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Web.Extension;
using Web.Jwt;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Authorization;
using Web.Util;
using System.Security.Claims;
using Web.Security;
using Web.Filter;

namespace Web.Controllers
{
    [ApiController]
    [Route("api/[controller]/[action]")]
    [QueryFilter]
    public abstract class MyApiBaseController<IDEntity>  : MyBaseController<IDEntity> where IDEntity : ID,new()
    {
        protected readonly IBaseBll<IDEntity> bll;
        public MyApiBaseController(IBaseBll<IDEntity> bll)
        {
            this.bll = bll;
        }
        /// <summary>
        /// 分页列表查询
        /// </summary>
        /// <remarks>
        /// <br>查询条件格式：api/实体名/List?sort=-Id&amp;name=武汉&amp;pageNo=1 </br>
        /// <br>sort：排序，值的格式为：+|-字段名,+|-字段名。如-Id根据Id字段递减排序；+Id根据Id字段递增排序。可多个字段排序：如+Id,-Added_time。注意：字段名必须是实体类里面的属性名，大小写保存一致</br>
        /// <br>pageNo：查询页码；&lt;=0则查询所有，默认1。</br>
        /// <br>pageSize：每页显示数量；&lt;=0则查询所有，默认12。</br>
        /// <br>条件查询，格式：字段名__操作符=值。如"parent.id__eq=1"、 ParentId=null如果不加操作符,默认是等于eq 即如：parent.id=1与parent.id__eq=1等价。注意：字段名必须是实体类里面的属性名，大小写保存一致</br>
        /// <br>条件查询操作符有：contains包含,eq等于,ne不等于,gt大于,gte大于等于,lt小于, lte小于等于,in包含,between在……之间。如果是in查询，多个值之间","分隔，比如“id__in=1,2,3”</br>
        /// </remarks>
        /// <param name="where">此参数用于根据查询字符串自动组装查询条件字符串参数，无须人工干预</param>
        /// <param name="excludes">排除要查询那些字段，比如提高查询效率，排除导航属性（即对象属性）</param>
        /// <returns></returns>
        [HttpGet]
        public virtual async Task<Result<Pagination<IDEntity>>> List([FromQuery] Dictionary<string, string> where, String excludes = null)
        {
            return Result<Pagination<IDEntity>>.Success("succeed").SetData(await bll.QueryAsync(where, excludes));
        } 
        /// <summary>
        /// 查询详情
        /// </summary>
        /// <remarks>
        /// 格式:api/实体名/Get/id值，如：api/role/1
        /// </remarks>
        /// <param name="id">要查询的id值，放在路径中</param>
        /// <param name="where">查询其他条件，条件格式与list查询的条件一致</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public virtual async Task<Result<IDEntity>> Get(int id, [FromQuery] Dictionary<string, string> where)
        {
            return Result<IDEntity>.Success("succeed").SetData(await bll.SelectOneAsync(where));
        }
        /// <summary>
        /// 添加实体对象
        /// </summary>
        /// <param name="o">实体对象不需要id属性值</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Result<object>> Add(IDEntity o)
        {
            return ModelState.IsValid ? (await bll.AddAsync(o) ? Result<object>.Success("添加成功") : Result<object>.Error("添加失败")) : Result<object>.Error("添加失败!" + ModelState.GetAllErrMsgStr(";")); ;
        }
        /// <summary>
        /// 修改实体对象
        /// </summary>
        /// <param name="o">实体对象必须有id属性，根据id修改实体对象</param>
        /// <returns></returns>
        [HttpPost]
        public virtual async Task<Result<object>> Update(IDEntity o)
        {
            return ModelState.IsValid ? (await bll.UpdateAsync(o) ? Result<object>.Success("修改成功").SetData(o) : Result<object>.Error("修改失败")) : Result<object>.Error("修改失败!" + ModelState.GetAllErrMsgStr(";")); ;
        }
        /// <summary>
        /// 删除实体对象
        /// </summary>
        /// <remarks>
        /// <br>（1）根据id单个删除，如：/api/Area/Delete/id值或/api/Area/Delete?id=1</br>
        /// <br>（2）根据id批量删除，如：/api/Area/Delete/1,2,3 或/apiArea/Delete?id = 1,2,3  多个id值用“,”隔开</br>
        /// <br>（3）条件批量删除，如：/api/Area/Delete?name=武汉  ，条件格式与list查询的条件一致</br>
        /// </remarks> 
        /// <param name="id">id值，单个值如：1，多个值如：1,2,3</param>
        /// <param name="where">查询其他条件，条件格式与list查询的条件一致</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public virtual async Task<Result<object>> Delete(string id,[FromQuery] Dictionary<string, string> where)
        {
            return await bll.DeleteAsync(where) ? Result<object>.Success("删除成功") : Result<object>.Error("删除失败");
        }
        /// <summary>
        /// 批量删除实体对象
        /// </summary>
        /// <remarks>
        /// <br>如：api/Area/BatchDelete?name=武汉 </br>
        /// <br>注：条件格式与list查询的条件一致</br>
        /// </remarks>
        /// <param name="where">此参数用于根据查询字符串自动组装查询条件字符串参数，无须人工干预</param>
        /// <returns></returns>
        [HttpPost]
        public virtual async Task<Result<object>> BatchDelete([FromForm] Dictionary<string, string> where)
        {
            return await bll.DeleteAsync(where) ? Result<object>.Success("删除成功") : Result<object>.Error("删除失败");
        }
    }
}